import os
import sys
import time

from my_tool import Color, Bash, File, Git

POM_PATH = 'pom.xml'
# TODO idea 路径
IDEA_PATH = '/Users/jl/IdeaProjects'
# 正式包名称
MVNREP = 'mvnrep'
# TODO 测试包名称
MVNREP2 = 'jialiang'
# TODO 正式包路径
MVNREP_PATH = IDEA_PATH + '/' + MVNREP
# TODO 测试包路径
MVNREP2_PATH = IDEA_PATH + '/' + MVNREP2
# TODO authkey
AUTHKEY = '1e9ec1e9c814bdf2dbb73a6b890c40c5'
VERSION = '1.0.0-SNAPSHOT'
JAR_FANTASYWORKS_PATH = '{}/{}/repository/cn/fantasyworks/{}/{}'.format(IDEA_PATH, '{}', '{}', VERSION)
JAR_FANCYLAB_PATH = '{}/{}/repository/cn/fancylab/{}/{}'.format(IDEA_PATH, '{}', '{}', VERSION)
FANCY_MODULE = 'src/main/resources/fancy-module.txt'
# TODO 跳过回退本地代码版本到正式包版本的包
JUMP_RESET_MODULES = ['sso', 'mall', '.DS_Store']
MAIN_BRANCHS = ['main', 'master']
# TODO 跳过无需切分支的模块
JUMP_BRANCH_MODULES = ['reserve-client', 'mall', 'theatre-merchant-client', 'theatre-sport', 'thvendor-client',
                       '.DS_Store']


def jar_package(force=False):
    """
    打包
    :param force: 是否强制打包，即使版本一直
    :return:
    """
    if not File.file_exits(POM_PATH):
        Color.red(POM_PATH + ' not exists')
        sys.exit(0)
    if Bash.is_cmd_out("grep 'fancy-springboot' pom.xml"):
        Color.red('主程序不能打包')
        sys.exit(0)
    cur_module_name = Bash.get_run_cmd_result('basename $(pwd)').replace('\n', '')
    module_names = cur_module_name
    if len(args) == 4:
        module_names = args[3]
    environment = 'test'
    if len(args) > 2:
        environment = args[2]
    if environment == 'test':
        Bash.only_run_cmd('git -C {}/{} pull'.format(IDEA_PATH, MVNREP2))
    else:
        Bash.only_run_cmd('git -C {}/{} pull'.format(IDEA_PATH, MVNREP))
    for module_name in module_names.split(','):
        if module_name == cur_module_name:
            Color.yellow(cur_module_name)
            Bash.only_run_cmd('git pull')
            # 获取当前版本
            commit = Git.get_commit('.')
            Color.green('commit ' + commit)
            pack(environment, commit, module_name, force)
        else:
            os.chdir(Bash.get_run_cmd_result('pwd').replace('\n', '').replace(cur_module_name, module_name))
            cur_module_name = Bash.get_run_cmd_result('basename $(pwd)').replace('\n', '')
            Color.yellow(cur_module_name)
            Bash.only_run_cmd('git pull')
            # 获取当前版本
            commit = Git.get_commit('.')
            Color.green('commit ' + commit)
            pack(environment, commit, module_name, force)


def pack(environment, commit, module_name, force):
    if environment == 'test':
        test_package(commit, module_name, force)
    elif environment == 'formal':
        formal_package(commit, module_name)
    elif environment == 'all':
        test_package(commit, module_name, force)
        formal_package(commit, module_name)
    else:
        Color.red('打包参数有误')
        sys.exit(0)
    jar_package_finish()


def mvn_module(module_name, package_name):
    """
    打包
    :param module_name:
    :param package_name:
    :return:
    """
    Color.green('开始打包')
    if not File.file_exits(FANCY_MODULE):
        Bash.only_run_cmd('mkdir -p src/main/resources/')
        Bash.only_run_cmd('echo {} >{}'.format(module_name, FANCY_MODULE))
        Bash.only_run_cmd('git log -1 >>{}'.format(FANCY_MODULE))
        Bash.only_run_cmd('mvn -q clean:clean')
    Bash.only_run_cmd('rm -fr {}/{}/repository/cn/fancylab/{}'.format(IDEA_PATH, package_name, module_name))
    Bash.only_run_cmd('rm -fr {}/{}/repository/cn/fantasyworks/{}'.format(IDEA_PATH, package_name, module_name))
    Bash.only_run_cmd(
        'mvn -q -Dmaven.test.skip=true deploy -DaltDeploymentRepository=fancy-lab::default::file:{}/{}/repository/'
        .format(IDEA_PATH, package_name))


def get_jar_commit(package_name, module_name):
    """
    获取 jar 包版本
    :param package_name:
    :param module_name:
    :return:
    """
    jar_commit_cmd = "cat fancy-module.txt | grep ^commit | awk -F ' ' '{print $2}'"
    jar_commit = ''
    if File.file_exits(JAR_FANTASYWORKS_PATH.format(package_name, module_name)):
        Bash.only_run_cmd(
            'jar -xf {}/{}/repository/cn/fantasyworks/{}/{}/{}-*-1.jar fancy-module.txt'.format(IDEA_PATH, package_name,
                                                                                                module_name, VERSION,
                                                                                                module_name))
        jar_commit = Bash.get_run_cmd_result(jar_commit_cmd)
        Bash.only_run_cmd('rm fancy-module.txt')
    elif File.file_exits(JAR_FANCYLAB_PATH.format(package_name, module_name)):
        Bash.only_run_cmd(
            'jar -xf {}/{}/repository/cn/fancylab/{}/{}/{}-*-1.jar fancy-module.txt'.format(IDEA_PATH, package_name,
                                                                                            module_name, VERSION,
                                                                                            module_name))
        jar_commit = Bash.get_run_cmd_result(jar_commit_cmd)
        Bash.only_run_cmd('rm fancy-module.txt')
    else:
        Color.red('jar 包不存在')
    return jar_commit


def test_package(commit, module_name, force):
    Color.green('测试打包')
    time.sleep(1)
    Bash.only_run_cmd('git -C {}/{} pull'.format(IDEA_PATH, MVNREP2))
    jar_commit = get_jar_commit(MVNREP2, module_name)
    Color.green('{} {} jar_commit {}'.format(MVNREP2, module_name, jar_commit))
    if commit == jar_commit and not force:
        Color.green('测试版本一致，跳过')
        return
    mvn_module(module_name, MVNREP2)


def formal_package(commit, module_name):
    Color.green('正式打包')
    time.sleep(1)
    branch = Git.get_branch('.')
    if branch not in MAIN_BRANCHS:
        Color.red('不在主干分支: {} {}'.format(module_name, branch))
        sys.exit(0)
    package_name = MVNREP
    Bash.only_run_cmd('git -C {}/{} pull'.format(IDEA_PATH, package_name))
    jar_commit = get_jar_commit(package_name, module_name)
    Color.green('{} {} jar_commit {}'.format(package_name, module_name, jar_commit))
    if commit == jar_commit:
        Color.green('正式版本一致，跳过')
        return
    mvn_module(module_name, package_name)


def jar_package_finish():
    if File.file_exits(FANCY_MODULE):
        Bash.only_run_cmd('rm {}'.format(FANCY_MODULE))
        Color.green('打包完成')


def jar_package_push():
    program_path = Bash.get_run_cmd_result('pwd').replace('\n', '')
    Color.green('当前目录：' + program_path)
    if len(args) > 2:
        if args[2] == 'test':
            test_push()
        elif args[2] == 'formal':
            formal_push()
        elif args[2] == 'all':
            test_push()
            formal_push()
        else:
            raise Exception('打包参数有误')
    else:
        test_push()
    Color.green('提交更新完成')
    os.chdir(program_path)


def test_push():
    """
    测试提交推送
    :return:
    """
    module_name = Bash.get_run_cmd_result('basename $(pwd)').replace('\n', '')
    Color.green('测试提交')
    time.sleep(1)
    os.chdir(MVNREP2_PATH)
    Bash.only_run_cmd('git pull')
    nothing_commit = Bash.get_run_cmd_result('git status | grep "nothing to commit"')
    if nothing_commit:
        Color.green("=== 测试当前没有新增或者修改的文件 ===")
        return
    Bash.only_run_cmd('git add . && git commit -m upgrade && git push')
    Bash.only_run_cmd(
        'curl "https://antadmin.lengliwh.com/mvnadmin/publish/push.xhtml?authKey={}&moduleName={}"'.format(AUTHKEY,
                                                                                                           module_name), True)


def formal_push():
    """
    正式提交推送
    :return:
    """
    Color.green('正式提交并更新 jar 包')
    time.sleep(1)
    os.chdir(MVNREP_PATH)
    Bash.only_run_cmd('git pull')
    nothing_commit = Bash.get_run_cmd_result('git status | grep "nothing to commit"')
    if nothing_commit:
        Color.green("=== 正式当前没有新增或者修改的文件 ===")
        return
    Bash.only_run_cmd('git add . && git commit -m upgrade && git push')
    Color.green('正式更新 jar 包')
    time.sleep(1)
    Bash.only_run_cmd('ssh root@devserver1 \'su maven -c "git -C /opt/mvnrep/mvnrep1/ pull"\'')


def reset_formal(path):
    """
    回退本地代码版本到正式包版本，便于 review 代码
    :return:
    """
    if path is None:
        Color.red('路径不存在')
        sys.exit(0)
    Bash.only_run_cmd('git -C {} pull'.format(MVNREP_PATH))
    files = []
    if len(args) > 3:
        for sure_module_name in args[3].split(','):
            files.append(path + sure_module_name)
    else:
        files = File.path_files(path)
    reset_paths = []
    formal_commit = {}
    formal_not_exist_modules = []
    for filepath in files:
        module_name = Bash.get_run_cmd_result('basename ' + filepath).replace('\n', '')
        if module_name in JUMP_RESET_MODULES:
            continue
        branch = Git.get_branch(filepath)
        if branch not in MAIN_BRANCHS:
            Color.red('不在主干分支: {} {}'.format(module_name, branch))
            sys.exit(0)
        nothing_commit = Bash.get_run_cmd_result('git -C {} status | grep "nothing to commit"'.format(filepath))
        if not nothing_commit:
            Color.yellow('{} 模块有未提交的代码'.format(module_name))
            return
        Bash.only_run_cmd('git -C {} pull'.format(filepath))
        formal_jar_commit = get_jar_commit(MVNREP, module_name)
        if not formal_jar_commit:
            formal_not_exist_modules.append(module_name)
        commit = Git.get_commit(filepath)
        if commit == formal_jar_commit:
            continue
        reset_paths.append(filepath)
        formal_commit[module_name] = formal_jar_commit
    if len(formal_not_exist_modules) > 0:
        Color.red('正式包版本不存在的模块: {}'.format(formal_not_exist_modules))
    Color.green('有变更的模块: {}'.format(list(formal_commit.keys())))
    for reset_path in reset_paths:
        module_name = Bash.get_run_cmd_result('basename ' + reset_path).replace('\n', '')
        formal_jar_commit = formal_commit[module_name]
        Bash.only_run_cmd('git -C {} reset {}'.format(reset_path, formal_jar_commit))


def branch_check(path, check_branchs):
    """
    查询/检出指定路径下的所有包到指定分支
    :param path:
    :param check_branchs: 需要检出的分支，支持多分支，如：brancha,branchb
    :return:
    """
    if path is None or check_branchs is None:
        Color.red('路径或分支不存在')
        sys.exit(0)
    files = File.path_files(path)
    checkout = 'N'
    if len(args) > 4:
        checkout = args[4]
    gitpull = False
    if len(args) > 5 and args[5] == 'pull':
        gitpull = True
    for filepath in files:
        module_name = Bash.get_run_cmd_result('basename ' + filepath).replace('\n', '')
        if module_name in JUMP_BRANCH_MODULES:
            if checkout == 'Y':
                Color.yellow('跳过 {}'.format(module_name))
            continue
        if checkout == 'Y':
            nothing_commit = Bash.get_run_cmd_result('git -C {} status | grep "nothing to commit"'.format(filepath))
            if not nothing_commit:
                Color.yellow('{} 模块有未提交的代码'.format(module_name))
                return
        local_branch = Git.get_branch(filepath)
        for check_branch in check_branchs.split(','):
            have_branch = Bash.get_run_cmd_result(
                'git -C {} branch -a | grep -E "^\\s*{}$|/{}$"'.format(filepath, check_branch, check_branch))
            if have_branch:
                if checkout == 'Y':
                    if local_branch == check_branch:
                        break
                    else:
                        Bash.only_run_cmd('git -C {} checkout {}'.format(filepath, check_branch), True)
                        if gitpull:
                            Bash.only_run_cmd('git -C {} pull'.format(filepath), True)
                        break
                else:
                    Color.green(module_name)


def git_pull(path):
    """
    拉取指定路径下的所有包
    :param path:
    :return:
    """
    if path is None:
        Color.red('路径不存在')
        sys.exit(0)
    files = File.path_files(path)
    for filepath in files:
        is_git = Git.is_git(filepath)
        if not is_git:
            Color.yellow('{} 非 Git 仓库'.format(filepath))
            continue
        Bash.only_run_cmd('git -C {} pull'.format(filepath), True)


if __name__ == '__main__':
    """
    # 打包
    python3 jar_package.py package [test/formal/all] [p1,p2,p3]
    # 强制打包
    python3 jar_package.py packageForce [test/formal/all] [p1,p2,p3]
    # 推送
    python3 jar_package.py push [test/formal/all] [p1,p2,p3]
    # 打包然后推送
    python3 jar_package.py packageAndPush [test/formal/all] [p1,p2,p3]
    # 回退到正式版本
    python3 jar_package.py resetFormal <path> [p1,p2,p3]
    # 检出/检查指定分支
    python3 jar_package.py branchCheck <path> <check_branchs> [checkout]
    # 拉取代码
    python3 jar_package.py gitpull <path>
    """
    # args = ['', 'branchCheck', '/Users/jl/IdeaProjects/theatre', 'fix_20240123_转赠修改', 'Y']
    args = sys.argv
    try:
        if args[1] == 'package':
            jar_package()
        elif args[1] == 'packageForce':
            jar_package(True)
        elif args[1] == 'push':
            jar_package_push()
        elif args[1] == 'packageAndPush':
            jar_package()
            jar_package_push()
        elif args[1] == 'resetFormal':
            reset_formal(args[2])
        elif args[1] == 'branchCheck':
            branch_check(args[2], args[3])
        elif args[1] == 'gitPull':
            git_pull(args[2])
        elif args[1] == 'help':
            print('pmvn [test/formal/all] [p1,p2,p3]')
        else:
            Color.red('参数有误')
    except BaseException as e:
        Color.red(e)
        sys.exit(0)
